/*
 * @Descripttion:
 * @version: 1.0.0
 * @Date: 2021-03-26 20:05:36
 * @LastEditTime: 2022-01-11 19:38:15
 */
import {
  GeoJsonDataSource,
  DataSource,
  ImageryLayer,
  ImageryProvider,
  UrlTemplateImageryProvider,
  Viewer,
  WebMapTileServiceImageryProvider,
  CustomDataSource,
  IonImageryProvider,
  BingMapsImageryProvider,
  ArcGisMapServerImageryProvider,
} from 'cesium';
import { ILayerRecord, LayerType } from '../CustomCesium';

/**
 * @descripttion: 图层记录管理器
 */
class LayerManager {
  private viewer: Viewer;
  private layers: ILayerRecord[];

  /**
   * @descripttion: 图层记录管理器
   */
  constructor(viewer: Viewer) {
    this.viewer = viewer;
    this.layers = [];
  }

  /**
   * @descripttion: 添加图层记录
   * @param {string} code 图层唯一标识
   * @param {LayerType} type 图层类型{0:DataSource 1:ImageryLayer}
   * @param {ImageryLayer | DataSource} layer 图层数据
   * @return {*}
   */
  private add(code: string, type: LayerType, layer: ImageryLayer | DataSource) {
    const result = undefined;
    if (code && Number.isInteger(type) && layer) {
      if (!this.isExists(code)) {
        this.layers.push({ code, layerType: type, layer });
      }
    }
    return result;
  }

  /**
   * @descripttion: 添加图层
   * @param {string} code
   * @param {ImageryProvider} layer
   * @param {boolean} show 默认是否展示
   * @param {number} index
   * @return {*}
   */
  addLayer(
    code: string,
    layer: ImageryProvider | ImageryLayer | DataSource | Promise<DataSource>,
    show = true,
    index?: number,
  ) {
    if (this.isExists(code)) return undefined;
    //影像提供者
    if (
      layer instanceof WebMapTileServiceImageryProvider ||
      layer instanceof UrlTemplateImageryProvider ||
      layer instanceof ArcGisMapServerImageryProvider ||
      layer instanceof BingMapsImageryProvider ||
      layer instanceof IonImageryProvider
    ) {
      const imageLayer = this.viewer.scene.imageryLayers.addImageryProvider(layer, index);
      imageLayer.show = show;
      return this.add(code, LayerType.IMAGERY_LAYER, imageLayer);
    }
    if (layer instanceof ImageryLayer) {
      this.viewer.scene.imageryLayers.add(layer, index);
      layer.show = show;
      return this.add(code, LayerType.IMAGERY_LAYER, layer);
    }
    if (
      layer instanceof DataSource ||
      layer instanceof GeoJsonDataSource ||
      layer instanceof CustomDataSource
    ) {
      layer.show = show;
      this.viewer.dataSources.add(layer);
      return this.add(code, LayerType.DATASOURCE, layer);
    }
    if (layer instanceof Promise) {
      this.viewer.dataSources.add(layer).then((datasource) => {
        datasource.show = show;
        return this.add(code, LayerType.DATASOURCE, datasource);
      });
    }
  }

  /**
   * @descripttion: 是否存在图层
   * @param {string} code 图层唯一标识
   * @return {boolean} 查询结果
   */
  isExists(code: string) {
    return this.layers.findIndex((item) => item.code === code) >= 0;
  }

  /**
   * @descripttion: 获取图层
   * @param {string} code 图层唯一标识
   * @return {LayerRecord} 图层记录
   */
  get(code: string) {
    if (this.isExists(code)) return this.layers.filter((layer) => layer.code === code)[0];
  }

  /**
   * @descripttion: 删除图层
   * @param {string} code 图层唯一索引
   * @return {void}
   */
  removeByCode(code: string, destroy = false) {
    let result = false;
    if (this.isExists(code)) {
      const { layerType, layer } = this.get(code)!;
      if (layerType === LayerType.DATASOURCE)
        this.viewer.dataSources.remove(layer as DataSource, destroy);
      if (layerType === LayerType.IMAGERY_LAYER)
        this.viewer.scene.imageryLayers.remove(layer as ImageryLayer, destroy);
      const newLayers = this.layers.filter((item) => item.code !== code);
      destroy && (this.layers = [...newLayers]);
      result = true;
    }
    return result;
  }
}
export default LayerManager;
